package com.ndp.fb.mq.service.schedulerservice.retention;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.ReflectionDBObject;
import com.ndp.fb.mongo.api.AdGroupRetentionMongoService;
import com.ndp.fb.mongo.api.AppRetentionMongoService;
import com.ndp.fb.mongo.model.AdGroupRetention;
import com.ndp.fb.mongo.model.AppRetention;
import com.ndp.fb.mq.api.service.schedulerservice.retention.RetentionRecordService;
import com.ndp.fb.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.*;

/**
 * Created by jacky.cheng on 2015/10/8.
 */
@Service
public class RetentionRecordServiceImpl implements RetentionRecordService {
    @Reference
    AppRetentionMongoService appRetentionMongoService;
    @Reference
    AdGroupRetentionMongoService adGroupRetentionMongoService;
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public boolean saveApp(File appFile, String type) throws FileNotFoundException {
        logger.info("app 留存数据存储开始。");
        BufferedReader br = new BufferedReader(new FileReader(appFile));
        try {
            //该文件只有一行数据
            String line = br.readLine();
            if (!StringUtils.hasText(line)) {
                logger.error("空文件。");
                return false;
            }
            AppRetention appRetention = new AppRetention();
            appRetention.parseLineData(line);
            appRetention.setType(type);
            updateOldApp(type, appRetention);
            //清空今天的open数据
            appRetention.setOpens(new HashMap<String, Integer>());
            appRetentionMongoService.save(appRetention);
            logger.info("app 留存数据存储成功。");
        } catch (FileNotFoundException e) {
            throw e;
        }catch (Exception e) {
            logger.error("app 留存数据存储失败。{}",e.getMessage());
            return false;
        }
        return true;
    }



    @Override
    public boolean saveAds(File adFile) throws FileNotFoundException {
        logger.info("ad 留存数据存储开始。");
        BufferedReader br = new BufferedReader(new FileReader(adFile));
        try {
            List<ReflectionDBObject> retentions=new ArrayList<>();
            while (true) {
                //多行数据
                String line = br.readLine();
                if (!StringUtils.hasText(line)){
                    logger.warn("空行");
                    break;
                }
                AdGroupRetention retention = new AdGroupRetention();
                retention.parseLineData(line);
                updateOldAd(retention);
                //清空今天的打开数据
                retention.setOpens(new HashMap<String, Integer>());
                retentions.add(retention);

                //批次存储
                if (retentions.size()>1000){
                    adGroupRetentionMongoService.saveAll(retentions);
                    retentions=new ArrayList<>();
                }
            }
            //最后不足一批的存一次
            adGroupRetentionMongoService.saveAll(retentions);
            logger.info("ad 留存数据存储成功。");
        } catch (FileNotFoundException e) {
            throw e;
        }catch (Exception e) {
            logger.error("ad 留存数据存储失败。{}",e.getMessage());
            return false;
        }
        return true;
    }

    private void updateOldApp(String type, AppRetention retention) {
        for (int i = 1; i <= 7; i++) {
            DBObject q = new BasicDBObject();
            q.put("Day", DateUtil.addDateByTypeAndOffset(retention.getDay(),Calendar.DATE,-i));
            q.put("AppId", retention.getAppId());
            q.put("Type", type);
            Iterator<DBObject> os = appRetentionMongoService.find(q);
            System.out.println(os.hasNext());;
            DBObject fs=new BasicDBObject();
            fs.put("$set",new BasicDBObject("Opens.open"+i,retention.getOpens().get("open"+i)));
            appRetentionMongoService.updates(q,fs);
        }
    }
    private void updateOldAd(AdGroupRetention retention) {
        for (int i = 1; i <= 7; i++) {
            DBObject q = new BasicDBObject();
            q.put("Day", DateUtil.addDateByTypeAndOffset(retention.getDay(),Calendar.DATE,-i));
            q.put("AdGroupId", retention.getAdGroupId());
            DBObject fs=new BasicDBObject();
            fs.put("$set",new BasicDBObject("Opens.open"+i,retention.getOpens().get("open"+i)));
            adGroupRetentionMongoService.updates(q,fs);
        }
    }
}
